package exteditapp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPopupMenu;

import exteditapp.action.IAction;
import exteditapp.state.IState;

/**
 * Default view for main module - simply: only JCustomProgressBar or Button, or Label
 * 
 * This is main interface of exteditapp application. It simplified to only one element per moment. It
 * can be progress bar, button or information label (which actually is just disabled button).
 * @author Arturas Smorgun, arturas@smorgun.lt
 * @version 2009.04.21
 */
public class ViewDefault extends IView {

	/**
	 * Interface button
	 */
	JButton button = new JButton();
	
	/**
	 * Progress bar
	 */
	JCustomizedProgressBar progress = new JCustomizedProgressBar();
	
	/**
	 * 
	 */
	JButton menuIcon = null;
	
	/**
	 * 
	 */
	JPopupMenu menuPopup = new JPopupMenu();
	
	/**
	 * Trigger, which saves current interface state - whether it represents progress bar or button
	 */
	boolean buttonMode;
	
	/**
	 * Action listener for mouse click on button. Is being used only then GUI is in button mode AND
	 * button is enabled for mouse presses.
	 */
//	MouseListener mListener;
	
	/**
	 * Constructor, which also sets controller for this interface.
	 * @param controller controller, by which we will be able to control module
	 */
	public ViewDefault(IController controller){
		super(controller);
		this.button.setBackground(Color.YELLOW);
		
		progress.setStringPainted(true);
		//progress.setForeground(Color.decode("#DEE7EC"));
		buttonMode = false;
	}
	
	/**
	 * Default constructor
	 */
	public ViewDefault(){
		progress.setStringPainted(true);
		//progress.setForeground(Color.decode("#DEE7EC"));
		buttonMode = false;
	}
	
	/**
	 * Updates state of current view - commonly used by Subject, then module's state changes.
	 * @param fileState new state of watched subject
	 */
	public void update(IState fileState) {
		if(fileState == null || fileState.getAction() == null)
			return;
		if(fileState.getAction().getItemCount() > 0){
			//System.out.println("VEIKIE "+fileState.getAction().getItemCount());
			buttonMode(fileState.getAction());
		}
		else{
			progressMode(fileState.getAction().getLabel(), fileState.getProgress());
		}
//		/**
//		 * Usually displayed soon after application start - invokes file download and open processes
//		 * After initialization is being replaced my Idle state
//		 */
//		if(fileState instanceof StateStarting){
//			buttonMode("EDIT IN EXTERNAL EDITOR", false);
//		}
//		/**
//		 * Application initialized and waiting for user to press on main button
//		 */
//		else if(fileState instanceof StateIdling){
//			buttonMode(fileState.getLabel(), (fileState.getProgress() == 0));
//			//System.out.println(fileState.getLabel()+fileState.getProgress());
//		}
//		/**
//		 * Application is initialized, but not started by user and app detected, that file was up-
//		 * dated after user got into this page. Shows some sort of error message
//		 */
//		else if(fileState instanceof StateIdlingUpdated){
//			buttonMode(fileState.getLabel(), false);
//		}
//		/**
//		 * Application is initialized, but not started by user and app detected, that file was locked
//		 * after user got into this page. Usually it is sign, that somebody else is modifying this
//		 * file. Shows some sort of notification and checks for updates every several seconds
//		 */
//		else if(fileState instanceof StateIdlingLocked){
//			buttonMode(fileState.getLabel(), false);
//		}
//		/**
//		 * Application is initializing - loading settings, parameters, starting iterator and others
//		 */
//		else if(fileState instanceof StateInitializing){
//			buttonMode("STARTING...", false);
//		}
//		/**
//		 * Application is locking working file on server
//		 */
//		else if(fileState instanceof StateLocking){
//			buttonMode("LOCKING...", false);
//		}
//		/**
//		 * Application is unlocking working file on server
//		 */
//		else if(fileState instanceof StateUnlocking){
//			buttonMode("UNLOCKING...", false);
//		}
//		/**
//		 * Application is downloading working file from server
//		 */
//		else if(fileState instanceof StateDownloading){
//			progressMode("DOWNLOADING FILE...", fileState.getProgress());
//		}
//		/**
//		 * Application is uploading working file to server
//		 */
//		else if(fileState instanceof StateUploading){
//			progressMode("SAVING FILE...", fileState.getProgress());
//		}
//		/**
//		 * Application is started, external file is opened and app is waiting for a changes to be
//		 * save in it
//		 */
//		else if(fileState instanceof StateWaiting){
//			buttonMode(fileState.getLabel(), (fileState.getProgress() == 0));
//		}
//		/**
//		 * Application is started, external file is opened and app detected, that some modifications
//		 * was saved in it. Usually will wait some time (depending on future saving activity) before
//		 * actually saving that changes into server (which is - uploading file back to server)
//		 */
//		else if(fileState instanceof StateEditing){
//			buttonMode(fileState.getLabel(), (fileState.getProgress() == 0));
//		}
//		/**
//		 * Application is started, external file is opened, app detected some modification made in
//		 * working file and modification timeout time was elapsed, which means that modification pro-
//		 * cess is (probably) ended and we need to save changes into server
//		 */
//		else if(fileState instanceof StateEditingDone){
//			progressMode("SAVING LAST CHANGES...", fileState.getProgress());
//		}
//		/**
//		 * Application is started, external file is opened, app detecting some modifications made in
//		 * working file, but certain (much) time passed from last save and app do it automatically
//		 * to prevent massive modifications lost
//		 */
//		else if(fileState instanceof StateEditingAutosave){
//			progressMode("AUTOSAVING CURRENT CHANGES...", fileState.getProgress());
//		}
//		/**
//		 * Application is started, external file is opened and user selected manual saving mode. In
//		 * this mode app do not track for a changes in file and user decides for himself then he
//		 * shoud save any modifications
//		 */
//		else if(fileState instanceof StateEditingManual){
//			buttonMode(fileState.getLabel(), (fileState.getProgress() == 0));
//		}
//		/**
//		 * Saving (upload) process ended just few moments before and we notify about it application
//		 * user
//		 */
//		else if(fileState instanceof StateUploadingDone){
//			buttonMode("CHANGES SAVED", false);
//		}
//		/**
//		 * Showing some kind of error or notification/information message
//		 */
//		else if(fileState instanceof StateError){
//			buttonMode(fileState.getLabel(), false);
//		}
	}
	
	/**
	 * Changes view to button mode. It can have custom label and be enabled or disabled
	 * @param label text on button
	 * @param isEnabled whether button can be pressed or not
	 * @return true if view changed, false if only label and state
	 */
	protected boolean buttonMode(IAction act){
		if(act == null)
			return false;
		
		Container contentPane = controller.getModule().getContentPane();
		
		//tune button
		boolean changed = false;
		//change text
		if(button.getText().compareTo(act.getItem(0).getLabel()) != 0){
			button.setText(act.getItem(0).getLabel());
			changed = true;
		}
		//change enabled
		if(button.isEnabled() != act.getItem(0).isEnabled()){
			button.setEnabled(act.getItem(0).isEnabled());
			changed = true;
		}
		//
		if(!changed)
			return false;
		
		ActionListener l[] = button.getActionListeners();
		if(l.length > 0){
			if(l[0] == act.getItem(0))
				return false;
			else{
				button.removeActionListener(l[0]);
			}
		}
		
		menuPopup.removeAll();
		if(act.getItemCount() > 1){
			menuIcon.setEnabled(true);
			for(int i = 1; i < act.getItemCount(); i++){
				menuPopup.add(act.getItem(i));
			}
			menuPopup.show(contentPane, 0, 0);
//			menuPopup.update(menuPopup.getGraphics());
			menuPopup.setVisible(false);
//			menuPopup.show();
//			menuPopup.show(false);
		}
		else
			this.menuIcon.setEnabled(false);
		
		button.addActionListener(act.getItem(0));
		//tune panel if needed
		if(!buttonMode){
			
			contentPane.remove(progress);
			contentPane.add(button, BorderLayout.CENTER);
			
			buttonMode = true;
			contentPane.repaint();
			progress.repaint();
			button.repaint();
			contentPane.validate();
			return true;
		}
		
		return false;
	}
	
	/**
	 * Changes view to progress bar mode. It shows some progress and also some kind of label
	 * @param label label on progress bar
	 * @param value progress bar value - percentage value from 0 to 100
	 * @return true if view changed, false if only label and progress
	 */
	protected boolean progressMode(String label, int value){
		if(progress.getString() != label)
			progress.setString(label);
		if(progress.getValue() != value)
			progress.setValue(value);
		if(buttonMode){
			Container contentPane = controller.getModule().getContentPane();
			
			ActionListener l[] = button.getActionListeners();
			if(l.length > 0)
				button.removeActionListener(l[0]);
			
			contentPane.add(progress, BorderLayout.CENTER);
			
			buttonMode = false;
			contentPane.repaint();
			progress.repaint();
			button.repaint();
			contentPane.validate();
			return true;
		}
		return false;
	}
	/**
	 * Changes view to progress bar mode. It shows some progress and also some kind of label
	 * @param label label label on progress bar
	 * @param value progress bar value - percentage value from 0 to 100
	 * @param fcolor front color of progress bar
	 * @return true if view changed, false if only label and progress
	 */
	protected boolean progressMode(String label, int value, Color fcolor){
		if(progress.getSelectionColor() != fcolor)
			progress.setSelectionColor(fcolor);
		return progressMode(label, value);
	}
	
	/**
	 *  Changes view to progress bar mode. It shows some progress and also some kind of label
	 * @param label label label on progress bar
	 * @param value progress bar value - percentage value from 0 to 100
	 * @param fcolor front color of progress bar
	 * @param bcolor back color of progress bar
	 * @return true if view changed, false if only label and progress
	 */
	protected boolean progressMode(String label, int value, Color fcolor, Color bcolor){
		if(progress.getSelectionBackground() != bcolor)
			progress.setSelectionBackground(bcolor);
		return progressMode(label, value, fcolor);
	}
	
	/**
	 * Method in which display of view for startup is initialized. Does nothing else.
	 */
	public void init() {
				
		//containter 
		
		Container contentPane = controller.getModule().getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.setBackground(Color.decode("#FFFFFF"));
				
		//sets current mode into button mode
		
		contentPane.add(button, BorderLayout.CENTER);
		
		menuIcon = new JButton(new ImageIcon(ModuleAppletDefault.class.getResource("img/arrow.gif")));
		menuIcon.setPreferredSize(new Dimension(20, 20));
		contentPane.add(menuIcon, BorderLayout.EAST);
		menuIcon.addMouseListener(new MouseListener(){
			public void mouseClicked(MouseEvent e) {
				Container contentPane = controller.getModule().getContentPane();
				menuPopup.show(contentPane, contentPane.getWidth()-menuPopup.getWidth(), contentPane.getHeight());
			}
			public void mouseEntered(MouseEvent e){
				mouseClicked(e);
			}
			public void mouseExited(MouseEvent e){
				menuPopup.setVisible(false);
			}
			public void mousePressed(MouseEvent e){}
			public void mouseReleased(MouseEvent e){}
		});
		
		contentPane.add(this.menuPopup);
		this.menuPopup.setVisible(true);
		
		this.buttonMode(null);
	}
}
